package site.xuqing.autohelper.script;

import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.List;

import site.xuqing.autohelper.StepScript;
import site.xuqing.autohelper.bean.StepBean;
import site.xuqing.autohelper.listener.OnStepListener;
import site.xuqing.autohelper.util.ListTraverseUtil;
import site.xuqing.autohelper.util.StepExecutor;

public abstract class StepScriptTraverse extends StepScript {
    private ListTraverseUtil listTraverseUtil;
    public StepScriptTraverse(){
        listTraverseUtil=new ListTraverseUtil();
    }

    /**
     * 获取录入的当前界面的列表
     * @param service 服务
     * @param stepBean 步骤
     * @param stepExecutor 帮助类
     * @param onStepListener 监听
     * @return 列表数据
     */
    protected abstract List<AccessibilityNodeInfo> getTraverseList(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener) throws Exception;

    /**
     * 录入到node后需要做的动作
     * @param service 服务
     * @param stepBean 步骤
     * @param stepExecutor 帮助类
     * @param onStepListener 监听
     * @param traverseNode 录入到的当前node
     * @return 是否退出录入
     */
    protected abstract boolean doTraverse(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener, AccessibilityNodeInfo traverseNode) throws Exception;

    /**
     * 当前页录入完成后需要执行的动作
     * @param service 服务
     * @param stepBean 步骤
     * @param stepExecutor 帮助类
     * @param onStepListener 监听
     * @return 是否全部录入完成
     */
    protected abstract boolean endTraverse(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener) throws Exception;

    /**
     * 列表为空
     * @param service 服务
     * @param stepBean 步骤
     * @param stepExecutor 帮助类
     * @param onStepListener 监听
     */
    protected abstract void traverseListEmpty(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener) throws Exception;

    @Override
    public void doStep(AccessibilityService service, StepBean stepBean, StepExecutor stepExecutor, OnStepListener onStepListener) throws Exception {
        AccessibilityNodeInfo scrollNode = stepExecutor.findStepInfoNode(service.getRootInActiveWindow(), stepBean);
        if (scrollNode != null) {
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                List<AccessibilityNodeInfo> traverseList = getTraverseList(service, stepBean, stepExecutor, onStepListener);
                if (!traverseList.isEmpty()) {
                    if (listTraverseUtil.isAllTraverse(traverseList)) {
                        scrollNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
                        Thread.sleep(200);
                    } else {
                        boolean breakTraverse=false;
                        for (int j = 0; j < traverseList.size(); j++) {
                            AccessibilityNodeInfo node = traverseList.get(j);
                            String sourceIdentity = listTraverseUtil.getSourceIdentity(node);
                            if (listTraverseUtil.getTraverseMark().containsKey(sourceIdentity) && listTraverseUtil.getTraverseMark().get(sourceIdentity)) {
                                continue;
                            }
                            listTraverseUtil.getTraverseMark().put(sourceIdentity, true);

                            if (doTraverse(service,stepBean, stepExecutor,onStepListener,node)) {
                                breakTraverse=true;
                                break;
                            }
                        }
                        if (breakTraverse){
                            break;
                        }
                    }
                    if(endTraverse(service, stepBean, stepExecutor, onStepListener)){
                        break;
                    }
                } else {
                    traverseListEmpty(service, stepBean, stepExecutor, onStepListener);
                    break;
                }
            }
        }
    }
}
